home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / roids / ship.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  6.8 KB  |  285 lines

  1. /*
  2.  * Copyright 1989 Digital Equipment Corporation
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software and its
  5.  * documentation for any purpose and without fee is hereby granted,
  6.  * provided that the above copyright notice appear in all copies and that
  7.  * both that copyright notice and this permission notice appear in
  8.  * supporting documentation, and that the name of Digital Equipment
  9.  * Corporation not be used in advertising or publicity pertaining to
  10.  * distribution of the software without specific, written prior
  11.  * permission.  Digital Equipment Corporation makes no representations
  12.  * about the suitability of this software for any purpose.  It is
  13.  * provided "as is" without express or implied warranty.
  14.  *
  15.  * DIGITAL EQUIPMENT CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO
  16.  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  17.  * FITNESS, IN NO EVENT SHALL DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR
  18.  * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  20.  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  21.  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  * Author:  Terry Weissman
  24.  *          weissman@decwrl.dec.com
  25.  */
  26.  
  27. /* ship.c - handle movement, etc. of the ship. */
  28.  
  29. #include "roids.h"
  30. #include "explode.bit"
  31.  
  32. #define MAXDIR 256
  33.  
  34.  
  35. static int shipx[MAXDIR][NPOINTS];
  36. static int shipy[MAXDIR][NPOINTS];
  37. static double velx[MAXDIR];
  38. static double vely[MAXDIR];
  39. int px[NPOINTS], py[NPOINTS];    /* What points describe the ships outline */
  40.                 /* now. */
  41.  
  42. static int orientation;
  43. double sx, sy;            /* The ship's current location (where the */
  44.                 /* center of it is, in units of pixels. */
  45. static double vx, vy;        /* The ship's current velocity (in units */
  46.                 /* of pixels per repaint.) */
  47. static int ex, ey;        /* Where we're painting an explosion. */
  48. static Boolean showingexplosion = FALSE;
  49.  
  50. static int dturn;
  51. static int goalx = -1, goaly;
  52. static Boolean thrust;
  53.  
  54.  
  55. void InitShip()
  56. {
  57.     int i, d;
  58.     double angle;
  59.     shipdestroyed = TRUE;
  60.     showingexplosion = FALSE;
  61.     shiptimerid = NULL;
  62.     orientation = 0;
  63.     vx = vy = 0.0;
  64.     dturn = 0;
  65.     thrust = FALSE;
  66.     d = shipradius;
  67.     if (d > shipradius) d = shipradius;
  68.     for (i=0 ; i < numdir ; i++) {
  69.     angle = i * 2 * M_PI / (double) numdir;
  70.     shipx[i][0] = (int) rint(d * cos(angle + M_PI_2));
  71.     shipy[i][0] = (int) rint(-d * sin(angle + M_PI_2));
  72.     shipx[i][1] = (int) rint(d * cos(angle + M_PI + M_PI_4));
  73.     shipy[i][1] = (int) rint(-d * sin(angle + M_PI + M_PI_4));
  74.     shipx[i][2] = (int) rint(d * cos(angle - M_PI_4));
  75.     shipy[i][2] = (int) rint(-d * sin(angle - M_PI_4));
  76.     velx[i] = cos(angle + M_PI_2);
  77.     vely[i] = -sin(angle + M_PI_2);
  78.     }
  79. }
  80.  
  81.  
  82.  
  83. void PaintShip(gc)
  84. GC gc;
  85. {
  86.     static double lx = -100.0, ly = -100.0;
  87.     static int lorient = -1;
  88.     int i, j, x, y;
  89.     BeginLines();
  90.     if (sx != lx || sy != ly || orientation != lorient) {
  91.     lx = sx;
  92.     ly = sy;
  93.     lorient = orientation;
  94.     for (i=0 ; i<NPOINTS ; i++) {
  95.         px[i] = sx + shipx[orientation][i];
  96.         py[i] = sy + shipy[orientation][i];
  97.     }
  98.     }
  99.     for (i=0 ; i<NPOINTS ; i++) {
  100.     j = (i + 1) % NPOINTS;
  101.     AddLine(px[i], py[i], px[j], py[j], gc);
  102.     }
  103.     EndLines();
  104. }
  105.  
  106.  
  107. void DestroyShip()
  108. {
  109.     XImage ximage;
  110.     PaintShip(backgc);
  111.     shipdestroyed = TRUE;
  112.     ex = sx - explode_width/2;
  113.     ey = sy - explode_height/2;
  114.     ximage.height = explode_height;
  115.     ximage.width = explode_width;
  116.     ximage.xoffset = 0;
  117.     ximage.format = XYBitmap;
  118.     ximage.data = (char *)explode_bits;
  119.     ximage.byte_order = LSBFirst;
  120.     ximage.bitmap_unit = 16; 
  121.     ximage.bitmap_bit_order = LSBFirst;
  122.     ximage.bitmap_pad = 16;
  123.     ximage.bytes_per_line = (ximage.width+15)/16 * 2;
  124.     ximage.depth = 1;
  125.     XPutImage(dpy, gamewindow, shipgc, &ximage,
  126.           0, 0, ex, ey, explode_width, explode_height);
  127.     showingexplosion = TRUE;
  128.     if (shiptimerid) XtRemoveTimeOut(shiptimerid);
  129.     shiptimerid = XtAddTimeOut(1000, MoveShip, (Opaque) MoveShip);
  130. }
  131.  
  132.  
  133.  
  134. void MoveShip(closure, id)
  135. Opaque closure;
  136. XtIntervalId id;
  137. {
  138.     int i, j, newx, newy;
  139.     if (closure != (Opaque) MoveShip) return;
  140.     if (shipdestroyed) {
  141.     if (showingexplosion) {
  142.         XClearArea(dpy, gamewindow, ex, ey, explode_width, explode_height,
  143.                FALSE);
  144.         showingexplosion = FALSE;
  145.         shiptimerid = XtAddTimeOut(2000, MoveShip, (Opaque) MoveShip);
  146.         return;
  147.     }
  148.     sx = gamewidth / 2.0;
  149.     sy = gameheight / 2.0;
  150.     if (!AreaForShipIsClear()) {
  151.         shiptimerid = XtAddTimeOut(100, MoveShip, (Opaque) MoveShip);
  152.         return;
  153.     }
  154.     if (shipsleft <= 0) Quit();
  155.     shipsleft--;
  156.     PaintScore();
  157.     shipdestroyed = FALSE;
  158.     vx = vy = 0.0;
  159.     }
  160.     shiptimerid = XtAddTimeOut(shipwait, MoveShip, (Opaque) MoveShip);
  161.     PaintShip(backgc);
  162.     if (goalx >= 0) dturn = FindGoalTurn();
  163.     if (dturn) {
  164.     orientation += dturn;
  165.     if (orientation < 0) orientation = numdir - 1;
  166.     else if (orientation >= numdir) orientation = 0;
  167.     }
  168.     if (thrust) {
  169.     vx += velx[orientation] * accper;
  170.     vy += vely[orientation] * accper;
  171.     vx = (vx > maxv) ? maxv : ((vx < -maxv) ? -maxv : vx);
  172.     vy = (vy > maxv) ? maxv : ((vy < -maxv) ? -maxv : vy);
  173.     }
  174.     sx += vx;
  175.     sy += vy;
  176.     sx = (sx < 0) ? sx + gamewidth : ((sx > gamewidth) ? sx - gamewidth : sx);
  177.     sy = (sy < 0) ? sy + gameheight: ((sy > gameheight)? sy - gameheight: sy);
  178.  
  179.     PaintShip(shipgc);
  180.  
  181.     if (CheckIfShipHitRocks())
  182.     DestroyShip();
  183. }
  184.  
  185.  
  186.  
  187. void ThrustOn()
  188. {
  189.     thrust = TRUE;
  190. }
  191.  
  192.  
  193. void ThrustOff()
  194. {
  195.     thrust = FALSE;
  196. }
  197.  
  198.  
  199. void RotateLeft()
  200. {
  201.     dturn = 1;
  202.     goalx = -1;
  203. }
  204.  
  205.  
  206. void RotateRight()
  207. {
  208.     dturn = -1;
  209.     goaly = -1;
  210. }
  211.  
  212.  
  213. void RotateOff()
  214. {
  215.     dturn = 0;
  216. }
  217.  
  218.  
  219. int FindGoalTurn()
  220. {
  221.     double dx, dy;
  222.     double theta;
  223.     int dgoal;
  224.     dx = goalx - sx;
  225.     dy = goaly - sy;
  226.     if (rint(dy) == 0 && rint(dy) == 0)
  227.     return 0;
  228.     theta = atan2(-dy, dx);
  229.     theta += 3 * M_PI_2;
  230.     dgoal = (theta * numdir) / (2 * M_PI);
  231.     dgoal = dgoal % numdir;
  232.     if (dgoal == orientation) return 0;
  233.     else if (orientation < dgoal) {
  234.     if (dgoal - orientation <= numdir / 2)
  235.         return 1;
  236.     else return -1;
  237.     } else {
  238.     if (orientation - dgoal <= numdir / 2)
  239.         return -1;
  240.     else return 1;
  241.     }
  242. }
  243.  
  244. void RotateToPoint(w, event, params, num_params)
  245. Widget w;
  246. XEvent *event;
  247. char **params;
  248. int *num_params;
  249. {
  250.     goalx = event->xbutton.x;
  251.     goaly = event->xbutton.y;
  252. }
  253.  
  254. void RotateMouseMoved(w, event, params, num_params)
  255. Widget w;
  256. XEvent *event;
  257. char **params;
  258. int *num_params;
  259. {
  260.     goalx = event->xbutton.x;
  261.     goaly = event->xbutton.y;
  262. }
  263.  
  264.     
  265. void StopRotateToPoint()
  266. {
  267.     goalx = -1;
  268.     dturn = 0;
  269. }
  270.  
  271.  
  272. void Fire()
  273. {
  274. #define MIKEVEL 4
  275.     double dx, dy;
  276.     if (!shipdestroyed) {
  277.         dx =  velx[orientation] * shotacc * 2;
  278.     dy =  vely[orientation] * shotacc * 2; 
  279.  
  280.     dx = dx * shotwait / shipwait;
  281.     dy = dy * shotwait / shipwait;
  282.     AddShot((double)px[0], (double)py[0], dx, dy);
  283.     }
  284. }
  285.